package net.imagine.backend.mockrmi.remote.provider.mina.client;

import java.net.InetSocketAddress;

import net.imagine.backend.mockrmi.util.Constants;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.core.session.IoSessionConfig;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.SocketSessionConfig;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

/**
 * Mina框架实现的客户端管理类
 * 
 * @author wuqh
 * @see IoConnector
 * @see IoSession
 */
public class MinaClientContext {
	private static final Log logger = LogFactory.getLog(MinaClientContext.class);

	private final IoConnector connector;

	public MinaClientContext() {
		this.connector = createConnector();
	}

	/**
	 * 创建IoConnector
	 * 
	 * @return 创建的IoConnector
	 */
	private IoConnector createConnector() {
		IoConnector connector = new NioSocketConnector(Constants.CLIENT_PROCESSOR_COUNT);
		connector.setConnectTimeoutMillis(Constants.CLIENT_CONN_TIMEOUT_MILLIS);

		IoSessionConfig config = connector.getSessionConfig();
		if(config instanceof SocketSessionConfig) {
			SocketSessionConfig socketConfig = (SocketSessionConfig) config;
			socketConfig.setSendBufferSize(Constants.CLIENT_SEND_BUFFER_SIZE);
			socketConfig.setReceiveBufferSize(Constants.CLIENT_RECEIVE_BUFFER_SIZE);
			socketConfig.setKeepAlive(Constants.CLIENT_KEEP_ALIVE);
		}
		config.setIdleTime(IdleStatus.BOTH_IDLE, Constants.CLIENT_IDLE_SECONDS);
		config.setUseReadOperation(true);
		config.setReadBufferSize(Constants.CLIENT_READ_BUFFER_SIZE);
		
		connector.getFilterChain().addLast(Constants.CLIENT_CODEC_FILTER_ID,
				new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));

		connector.setHandler(new MinaClientIoHandler());

		return connector;
	}

	/**
	 * 创建IoSession
	 * 
	 * @param domain
	 *            服务端地址
	 * @param port
	 *            服务器端口号
	 * @return 创建的IoSession
	 */
	public IoSession createSession(String domain, int port) {
		try {
			ConnectFuture future = connector.connect(new InetSocketAddress(domain, port));
			future.awaitUninterruptibly();
			IoSession session = future.getSession();
			session.getConfig().setUseReadOperation(true);
			return session;
		} catch (Exception e) {
			logger.warn("create session failed", e);
			return null;
		}
	}

	/**
	 * 关闭IoSession（需要等待IO完成）
	 * 
	 * @param session
	 *            需要关闭的session
	 */
	public void releaseSession(IoSession session) {
		session.close(false);
	}

	/**
	 * 关闭管理的IoConnector，结束线程（需要等待IO完成）
	 * 
	 */
	public void releaseConnector() {
		connector.dispose(true);
	}
}
